// Definim o sortare topologica ca fiind o inlantuire a nodurilor unui graf 
// orientat in functie de gradul exterior al fiecarei muchii (nr nodurilor care
// ajung in muchie). Sortarea se poate face in timp O(N+M) folosind o coada.
// Initial punem in coada nodurile cu grad minim dupa care parcurgem vecinii 
// nodului din varf decrementand gradul vecinilor. La fiecare pas scoatem varful
// stivei si il punem in configuratia sortarii. Cand intalnim un element cu grad
// exterior 0 il introducem in coada si continuam procedeul pana coada se 
// goleste.

#include <queue>
#include <vector>
#include <fstream>

using namespace std;

#define Nmax 50011

ifstream F("sortaret.in");
ofstream G("sortaret.out");

int N,M; 

queue< int > Q,Rez; 
vector< int > Leg[Nmax]; 

int Grad[Nmax];

int main()
{
	F>>N>>M;
	for ( int i=1;i<=M;++i )
	{
		int x,y;
		F>>x>>y;
		Leg[x].push_back( y );
		++ Grad[y];
	}
	
	for ( int i=1;i<=N;++i )
		if ( !Grad[i] )
			Q.push( i );
	
	while ( Q.size() )
	{
		int Nod=Q.front();
		Q.pop();
		
		for ( vector<int>::iterator it=Leg[ Nod ].begin(); it!=Leg[ Nod ].end() ; ++it )
			if ( Grad[ *it ] )
			{
				--Grad[ *it ];
				if ( ! Grad[ *it ] )
					Q.push( *it );
			}
		
		Rez.push( Nod );
	}
	
	for ( ;Rez.size(); Rez.pop() ) G<< Rez.front() <<' ';
	G<<'\n';
}
